#ifndef __MY__DATA__
#define	__MY__DATA__
#include<unordered_map>
#include<pthread.h>
#include<vector>
#include"util.hpp"
#include"config.hpp"
namespace cloud{
	typedef struct BackInfo{
		bool _pack_flag;
		size_t _fsize;
		time_t _atime;
		time_t _mtime;
		std::string _real_path;
		std::string _pack_path;
		std::string _url;
		bool NewBackInfo(const std::string realpath){
			cloud::Config* config=cloud::Config::GetInstance();
			cloud::FileUtil fu(realpath);
			std::string packdir=config->GetPackDir();
			std::string packsuffix=config->GetPackFileSuffix();
			std::string downloapprefix=config->GetDownloapPrefix();
			this->_pack_flag=false;
			this->_fsize=fu.FileSize();
			this->_atime=fu.LastATime();
			this->_mtime=fu.LastMTime();
			this->_real_path=realpath;
			this->_pack_path=packdir+fu.FileName()+packsuffix;
			this->_url=downloapprefix+fu.FileName();
			return true;
		}
	
		}BackInfo;

	typedef struct DataManager{
			std::string _backup_file;
			pthread_rwlock_t _rwlock;
			//以url为key值，backinfo为值的图
			std::unordered_map<std::string ,BackInfo> _table;
			
			DataManager()
			{	
				_backup_file=Config::GetInstance()->GetBackupFile();
				pthread_rwlock_init(&_rwlock,NULL);
				InitLoad();
			}
			~DataManager()
			{
				pthread_rwlock_destroy(&_rwlock);
			}

			
			bool Insert(BackInfo &info){
			pthread_rwlock_wrlock(&_rwlock);
			_table[info._url]=info;
			pthread_rwlock_unlock(&_rwlock);
			return true;
			}
			bool Updata(BackInfo &info){			
				pthread_rwlock_wrlock(&_rwlock);
				_table[info._url]=info;
				pthread_rwlock_unlock(&_rwlock);
				return true;
			}
			bool GetOneByUrl(const std::string &url,BackInfo *Info){
				pthread_rwlock_wrlock(&_rwlock);
				auto it=_table.begin();
				it=_table.find(url);
				if(it==_table.end())
					return false;
				pthread_rwlock_unlock(&_rwlock);
				*Info=it->second;
				return true;
			}
			bool GetOneByRealPath(std::string &realpath,BackInfo * info){
				//直接遍历，通过second的成员来确定
				pthread_rwlock_wrlock(&_rwlock);
				auto it=_table.begin();
				for(;it!=_table.end();++it){
					if(it->second._real_path==realpath)
						*info=it->second;				
				}
				if(it==_table.end())
					return false;
				pthread_rwlock_unlock(&_rwlock);
				return true;
			}
			bool GetAll(std::vector<BackInfo> *arry){
				pthread_rwlock_wrlock(&_rwlock);
				auto it=_table.begin();
				for(;it!=_table.end();++it){
					arry->push_back(it->second);				
				}
				
				pthread_rwlock_unlock(&_rwlock);
				return true;
			}
			bool InitLoad(){
				//读取文件
				FileUtil fu(_backup_file);
				if(fu.Exists()==false)
					return true;
				std::string body;
				fu.GetContent(&body);
				Json::Value root;
				//先反序列化，获取一个Value
				JsonUtil::UnSerialize(body,&root);
				//再逐个插入
				for(int i=0;i<root.size();i++){
					BackInfo info;
					info._pack_flag=root[i]["pack_flag"].asBool();
					info._fsize=root[i]["fsize"].asInt64();
					info._atime=root[i]["atime"].asInt64();
					info._mtime=root[i]["mtime"].asInt64();
					info._real_path=root[i]["real_path"].asString();
					info._pack_path=root[i]["pack_path"].asString();
					
					info._url=root[i]["url"].asString();
					
					Insert(info);
				}
				return true;

			}
			bool Storage(){
				//先获取数据
				std::vector<BackInfo> arry;
				this->GetAll(&arry);
				Json::Value root;
				//遍历存放进value root
				for(int i=0;i<arry.size();i++){
					Json::Value tem;
					tem["pack_flag"]=arry[i]._pack_flag;
					tem["fsize"]=(Json::Value::Int64)arry[i]._fsize;
					tem["atime"]=(Json::Value::Int64)arry[i]._atime;
					tem["mtime"]=(Json::Value::Int64)arry[i]._mtime;
					tem["pack_path"]=arry[i]._pack_path;
					tem["real_path"]=arry[i]._real_path;
					tem["url"]=arry[i]._url;
					root.append(tem);
				}
				//将root序列化	
				std::string body;
				JsonUtil::Serialize(root,&body);
				//保存至文件完成持久化储存
				FileUtil fu(_backup_file);
				fu.SetContent(body);
				return true;
			}
	}DataManager;
}








#endif
